package canraid.agent.implementations;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
import android.widget.EditText;
import android.widget.TextView;

import canraid.agent.Cagent;
import canraid.agent.Iagent;
import canraid.config.Properties;
import canraid.debug.Level;
import canraid.debug.Logger;
import canraid.gui.BluetoothList;

public class EasyStartAgent extends Cagent {
	private final int NAME=canraid.gen.R.id.buttonActionEasyStart;
	private Activity activity=null;
	public volatile boolean callBackBT_OK=false;
	public volatile String callBackBT_device="";
	public volatile boolean callBackBT_enable=false;
	public volatile boolean callBackBT_choice=false;
	private boolean secureConnection =true;
	
	private BluetoothSocket mmSocket =null;
	private InputStream mmInStream = null;
	private OutputStream mmOutStream = null;
	private HttpURLConnection connection = null;
	private BufferedReader streamIn = null;
	private DataOutputStream  streamOut = null;
	
	private Handler[] handlers=null;

	public EasyStartAgent(Activity activity, boolean secureConnection) {
		super(1000);
		this.activity=activity;
		this.secureConnection=secureConnection;
	}
	
	public int getAgentName(){
		return NAME;
	}
	
	protected boolean __setup(){
        handlers = getPoolExternalHandlers();
		return true;
	}
	
	protected boolean __loop(){
		try{
			String textBT="@@TEXTBT@@";
			String sendNTW="@@SENDNTW@@";
			String textNTW="@@TEXTNTW@@";
			String commandNTW="CANRAID=@@NONE@@";
			BluetoothAdapter mBluetoothAdapter = null;
			BluetoothDevice mmDevice=null;
			
			for(int h=0; h<handlers.length;h++){
				handlers[h].obtainMessage(Iagent.ACTION_EASY_START, 0, -1, null).sendToTarget();
			}
	        
	        /*
			 * canraid.gen.R.id.imageBtActiving
			 */
	        try{
	        	for(int h=0; h<handlers.length;h++){
	        		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageBtActiving, Iagent.ACTION_EASY_START_WAIT, null).sendToTarget();
	        	}
	        	
	        	Thread.sleep(5000);        	
	        	Logger.setLog((Object)this,Level.ASSERT,"__loop(): canraid.gen.R.id.imageBtActiving: "+canraid.gen.R.id.imageBtActiving);	
	    		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
	    		
	    		if (mBluetoothAdapter == null) {	
	    			if (Properties.SIMULATION)
	    				throw new Exception("SIMULATION");
	    			else
	    				throw new Exception("ERROR-2");			
	    		}
	    		
	    		if (!mBluetoothAdapter.isEnabled()) {
	    			callBackBT_enable=false;
	                callBackBT_OK=false;
	                
	                if (!isRunning())
                		throw new Exception("ABORT");
	                
	    			Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
	                activity.startActivityForResult(enableIntent, Iagent.REQUEST_EASY_ENABLE_BT);
	                
	                while (!callBackBT_enable){
	                	Thread.sleep(1000);
	                }
	                
	                if (!callBackBT_OK){
	                	if (Properties.SIMULATION)
		    				throw new Exception("SIMULATION");
		    			else
		    				throw new Exception("ERROR-3");	
	                }
	    		};
	    		
	    		if (!isRunning())
            		throw new Exception("ABORT");
	    		
	    		if (callBackBT_device.equals("")){
		    		callBackBT_choice=false;
		    		Intent serverIntent = new Intent(activity, BluetoothList.class);
		    		activity.startActivityForResult(serverIntent, Iagent.REQUEST_EASY_CHOICE_DEVICE_BT);
		    		
		    		while (!callBackBT_choice){
		    			Thread.sleep(1000);
	                }
		    		
	                if (callBackBT_device.equals("")){
	                	if (Properties.SIMULATION)
		    				throw new Exception("SIMULATION");
		    			else
		    				throw new Exception("ERROR-4");	
	                }
	    		}
	    		
	    		if (!isRunning())
                	throw new Exception("ABORT");
	    		
    			if (mBluetoothAdapter.isDiscovering()) {
    	        	mBluetoothAdapter.cancelDiscovery();
    	        }
    			
    			if (!isRunning())
                	throw new Exception("ABORT");
    			
    			mmDevice=mBluetoothAdapter.getRemoteDevice(callBackBT_device);
    			
				UUID uuid=Properties.MY_UUID;
	            if (secureConnection) 
	            	mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
	            else
	            	mmSocket = mmDevice.createInsecureRfcommSocketToServiceRecord(uuid);
	
	            mmSocket.connect();
    		            	
    			if (!isRunning())
                	throw new Exception("ABORT");
    				
    	        mmInStream = mmSocket.getInputStream();
    	        mmOutStream = mmSocket.getOutputStream();
	    		
	    		for(int h=0; h<handlers.length;h++){
	        		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageBtActiving, Iagent.ACTION_EASY_START_OK, null).sendToTarget();
	        	}
			}
			catch(Exception e){
				Logger.setLog(this,Level.ERROR,"__loop(). Running failed. Error("+e.getMessage()+")");
				int indexError=5;
				String messageError=e.getMessage();
				if (messageError==null)
					messageError="";
				
				if (messageError.equals("ABORT")){
					indexError=1;
				}
				else if(messageError.equals("ERROR-2")){
					indexError=2;
				}
				else if(messageError.equals("ERROR-3")){
					indexError=3;
				}
				else if(messageError.equals("ERROR-4")){
					indexError=4;
				}
				else if(messageError.equals("SIMULATION")){
					indexError=9;
				}
				for(int h=0; h<handlers.length;h++){
					handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageBtActiving, Iagent.ACTION_EASY_START_NOT_OK, null).sendToTarget();
					handlers[h].obtainMessage(Iagent.ACTION_EASY_START_ERROR, indexError, -1, null).sendToTarget();
				}
				if (!Properties.SIMULATION)
    				return false;
			}
	        
	        /*
			 * canraid.gen.R.id.imageBtFirstDownloading
			 */
	        try{
	        	for(int h=0; h<handlers.length;h++){
	        		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageBtFirstDownloading, Iagent.ACTION_EASY_START_WAIT, null).sendToTarget();
	        	}
	        	
	        	Thread.sleep(5000);
	        	
	        	Logger.setLog((Object)this,Level.ASSERT,"__loop(): canraid.gen.R.id.imageBtFirstDownloading: "+canraid.gen.R.id.imageBtFirstDownloading);
	        	
	        	if (!isRunning())
            		throw new Exception("ABORT");
	        	
	        	mmOutStream.write(Properties.COMMAND_BT[0].getBytes());
	        	
	        	int byteReceived=0;
	        	int count=0;
	        	textBT="";
	        	
	        	do{	        		
	        		Thread.sleep(1000);
	        		
	        		if (!isRunning())
                		throw new Exception("ABORT");
	        		
	        		byteReceived=mmInStream.available();
	        		if (byteReceived>0){
	        			int in;
	        			while((in=mmInStream.read())!= -1){
	        				textBT += (char)in;
	        			}
	        		}
	        		count++;
	        	}while(byteReceived<1 && count<4);
	    		
	        	if(byteReceived==0){
	        		if (Properties.SIMULATION)
	    				throw new Exception("SIMULATION");
	    			else
	    				throw new Exception("ERROR-6");	
	        	}
	        	
	        	for(int h=0; h<handlers.length;h++){
	        		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageBtFirstDownloading, Iagent.ACTION_EASY_START_OK, null).sendToTarget();
	        	}
			}
			catch(Exception e){
				Logger.setLog(this,Level.ERROR,"__loop(). Running failed. Error("+e.getMessage()+")");
				int indexError=5;	//Confermato!!
				String messageError=e.getMessage();
				if (messageError==null)
					messageError="";
				
				if (messageError.equals("ABORT")){
					indexError=1;
				}
				else if(messageError.equals("ERROR-6")){
					indexError=6;
				}
				else if(messageError.equals("SIMULATION")){
					indexError=9;
				}
				for(int h=0; h<handlers.length;h++){
					handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageBtFirstDownloading, Iagent.ACTION_EASY_START_NOT_OK, null).sendToTarget();
					handlers[h].obtainMessage(Iagent.ACTION_EASY_START_ERROR, indexError, -1, null).sendToTarget();
				}
				if (!Properties.SIMULATION)
    				return false;
			}
	        
	        /*
			 * canraid.gen.R.id.imageNtwRequest
			 */
	        try{
	        	for(int h=0; h<handlers.length;h++){
	        		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageNtwRequest, Iagent.ACTION_EASY_START_WAIT, null).sendToTarget();
	        	}

	        	Thread.sleep(5000);
	        	
	        	Logger.setLog((Object)this,Level.ASSERT,"__loop(): canraid.gen.R.id.imageNtwRequest: "+canraid.gen.R.id.imageNtwRequest);
	        	ConnectivityManager connMgr = (ConnectivityManager)activity.getSystemService(Context.CONNECTIVITY_SERVICE);
	    		NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
	        	if( !(networkInfo != null && networkInfo.isConnected()) ){
	        		if (Properties.SIMULATION)
	    				throw new Exception("SIMULATION");
	    			else
	    				throw new Exception("ERROR-7");	
	        	}
	        	if (!isRunning())
            		throw new Exception("ABORT");
	
	        	URL url = new URL(Properties.URL_NETWORK);
		        connection = (HttpURLConnection) url.openConnection();
		        connection.setReadTimeout(5000 /* milliseconds */);
		        connection.setConnectTimeout(7000 /* milliseconds */);
		        connection.setDoOutput(true);
		        connection.setRequestMethod("POST");
		        
		        connection.connect();
		        if (!isRunning())
            		throw new Exception("ABORT");
		        
		        streamOut = new DataOutputStream (connection.getOutputStream());
		        
	        	//Write to URL
		        sendNTW=textBT;
				commandNTW="CANRAID="+Uri.encode(new String(sendNTW));
	
				streamOut.write(commandNTW.getBytes());
				streamOut.flush();
				
				for(int h=0; h<handlers.length;h++){
	        		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageNtwRequest, Iagent.ACTION_EASY_START_OK, null).sendToTarget();
	        	}
			}
			catch(Exception e){
				Logger.setLog(this,Level.ERROR,"__loop(). Running failed. Error("+e.getMessage()+")");
				int indexError=8;
				String messageError=e.getMessage();
				if (messageError==null)
					messageError="";
				
				if (messageError.equals("ABORT")){
					indexError=1;
				}
				else if(messageError.equals("ERROR-7")){
					indexError=7;
				}
				else if(messageError.equals("SIMULATION")){
					indexError=9;
				}
				for(int h=0; h<handlers.length;h++){
					handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageNtwRequest, Iagent.ACTION_EASY_START_NOT_OK, null).sendToTarget();
					handlers[h].obtainMessage(Iagent.ACTION_EASY_START_ERROR, indexError, -1, null).sendToTarget();
					
				}
				if (!Properties.SIMULATION)
    				return false;
			}
	        
	        /*
			 * canraid.gen.R.id.imageGetTicket
			 */
	        try{
	        	for(int h=0; h<handlers.length;h++){
	        		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageGetTicket, Iagent.ACTION_EASY_START_WAIT, null).sendToTarget();
	        	}

	        	Thread.sleep(5000);
	        	
	        	Logger.setLog((Object)this,Level.ASSERT,"__loop(): canraid.gen.R.id.imageGetTicket: "+canraid.gen.R.id.imageGetTicket);

	        	//Read to URL
        		if (!isRunning())
            		throw new Exception("ABORT");
        		
				String auxText="";
				streamIn  = new BufferedReader(new InputStreamReader(connection.getInputStream()));
	        	String inputLine;
	            while ((inputLine = streamIn.readLine()) != null) 
	            	auxText= auxText + inputLine;
	            
	            textNTW= Uri.decode(new String(auxText));
	            
	            for(int h=0; h<handlers.length;h++){
	        		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.textIdTicket, 0, textNTW).sendToTarget();
	        		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageGetTicket, Iagent.ACTION_EASY_START_OK, null).sendToTarget();
	            }    	
	        	
			}
			catch(Exception e){
				Logger.setLog(this,Level.ERROR,"__loop(). Running failed. Error("+e.getMessage()+")");
				int indexError=8;
				String messageError=e.getMessage();
				if (messageError==null)
					messageError="";
				
				if (messageError.equals("ABORT")){
					indexError=1;
				}
				for(int h=0; h<handlers.length;h++){
					handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageGetTicket, Iagent.ACTION_EASY_START_NOT_OK, null).sendToTarget();
					handlers[h].obtainMessage(Iagent.ACTION_EASY_START_ERROR, indexError, -1, null).sendToTarget();
				}
				if (!Properties.SIMULATION)
    				return false;
			}
	        
	        /*
			 * canraid.gen.R.id.imageReadyToRemoteInteraction
			 */
	    	for(int h=0; h<handlers.length;h++){
	    		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageReadyToRemoteInteraction, Iagent.ACTION_EASY_START_WAIT, null).sendToTarget();
	    	}

	    	Thread.sleep(5000);
	    	
	    	Logger.setLog((Object)this,Level.ASSERT,"__loop(): canraid.gen.R.id.imageReadyToRemoteInteraction: "+canraid.gen.R.id.imageReadyToRemoteInteraction);
	    	boolean exit=false;
	    	do{
		    	try{
		    		if (!isRunning())
                		throw new Exception("ABORT");
		    		
		        	ConnectivityManager connMgr = (ConnectivityManager)activity.getSystemService(Context.CONNECTIVITY_SERVICE);
		    		NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
		        	if( !(networkInfo != null && networkInfo.isConnected()) ){
		        		Thread.sleep(5000);
		        		throw new Exception("ERROR-8");
		        	}
		
		        	URL url = new URL(Properties.URL_NETWORK);
			        connection = (HttpURLConnection) url.openConnection();
			        connection.setReadTimeout(5000 /* milliseconds */);
			        connection.setConnectTimeout(7000 /* milliseconds */);
			        connection.setDoOutput(true);
			        connection.setRequestMethod("POST");
			        connection.connect();
			        streamOut = new DataOutputStream (connection.getOutputStream());
			        
		        	//Write to URL
			        sendNTW="READY";
					commandNTW="CANRAID="+Uri.encode(new String(sendNTW));
		
					streamOut.write(commandNTW.getBytes());
					streamOut.flush();
					
					//Read to URL
					String auxText="";
					streamIn  = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		        	String inputLine;
		            while ((inputLine = streamIn.readLine()) != null) 
		            	auxText= auxText + inputLine;
		            
		            textNTW= Uri.decode(new String(auxText));
		            
		            if (textNTW.equals(sendNTW))
		            	exit=true;
		    	}
		    	catch(Exception e){
		    		//Esci con errore SOLO in caso di ABORT
		    		String messageError=e.getMessage();
					if (messageError==null)
						messageError="";
					
		    		if (messageError.equals("ABORT")){
		    			Logger.setLog(this,Level.ERROR,"__loop(). Running failed. Error("+e.getMessage()+")");
						for(int h=0; h<handlers.length;h++){
							handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageReadyToRemoteInteraction, Iagent.ACTION_EASY_START_NOT_OK, null).sendToTarget();
							handlers[h].obtainMessage(Iagent.ACTION_EASY_START_ERROR, 1, -1, null).sendToTarget();
						}
						if (!Properties.SIMULATION)	//Confermato!
		    				return false;
		    		}
		    	}
	    	}while(!exit);
	    	
	    	for(int h=0; h<handlers.length;h++){
	    		handlers[h].obtainMessage(Iagent.ACTION_EASY_START, canraid.gen.R.id.imageReadyToRemoteInteraction, Iagent.ACTION_EASY_START_OK, null).sendToTarget();
	    	}
		}
		
        catch (Exception e3){
        	
        }
        finally{
			close();
		}
		
		return false;
	}

	public void close() {
		try {
        	if (streamIn!=null)
        		streamIn.close();
        } 
        catch (IOException e2) {}
		
		try {
        	if (streamOut!=null)
        		streamOut.close();
        } 
        catch (IOException e2) {}
		
		try {
        	if (mmSocket!=null)
        		mmSocket.close();
        } 
        catch (IOException e2) {}
		
		if (connection!=null)
			connection.disconnect();
		
		connection=null;
		streamIn=null;
		streamOut=null;
		mmSocket=null;
	}

	protected boolean __implementMyHandler(Message msg) {
		Logger.setLog(this,Level.ASSERT,"__implementMyHandler().");
		
		return false;
	}

}
